<?php
/**
 * 19、设计模式学习-备忘录模式
 * 游戏控制器
 * 2019年12月30日14:49:53
 */
namespace Application\Controller;

class GameMementoController extends BaseController
{
    // 使用简单的备忘录模式
    public function useSimpleMemento()
    {
        // 实例化游戏
        $game = new \Application\Common\Memento\SimpleMemento\Game();
        // 设置关卡
        $game -> setState('第一关');
        // 存档
        $game -> setMemento();
        // 进入下一关卡
        $game -> setState('第二关');
        // 打印关卡信息
        $game -> getStateInfo();
        // 恢复存档
        $game = $game -> getMemento();
        // 打印关卡信息
        $game -> getStateInfo();
        // 总结：较为简单，本质上是对象克隆的再次使用，只能对整体备忘，不能对细节备忘，如果使用此简单模式对细节备忘，那么这个类的职责就过多了
    }
    // 使用较为复杂的备忘模式
    public function useMemento()
    {
        // 实例化游戏
        $game = new \Application\Common\Memento\Memento\Game();
        // 设置关卡
        $game -> setStatus('第一关');
        // 打印关卡信息
        $game -> getStatusInfo();
        // 实例化备忘录管理类-引用传参
        $game_memento_manager = new \Application\Common\Memento\Memento\Manager($game);
        // 存档-游戏关卡
        echo '>> 存档-保存游戏关卡<br />';
        $game_memento_manager -> setMemento('status');
        // 进入下一关
        echo '>> 进入下一关<br />';
        $game -> setStatus('第二关');
        // 打印关卡信息
        $game -> getStatusInfo();
        // 恢复存档
        echo '>> 恢复存档<br />';
        $game_memento_manager -> getMemento('status');
        // 打印关卡信息
        $game -> getStatusInfo();
        // 总结：较为复杂，且类的方法命令需要一定规范，但能备忘一个类的多个属性
        // 总结：备忘录类与备忘录管理类都可以写成基类-实现类继承基类的形式，只不过要实例化的类对了而已，但责任更加明确
        // 关键：只要被备忘的类实现相应的 set|get 属性的方法，类感知不到本身会被备忘，而通过备忘管理类类管理备忘类与被备忘类。
        // 关键：被备忘类之所以能恢复之前的属性值，是因为传入管理类中的参数为引用传参
    }
}
